package cn.yitun.chat.yitunchatbasesdk.server.im.dispatcher.handler.impl;

import cn.yitun.chat.yitunactiondispatch.ActionDispatcher;
import cn.yitun.chat.yitunactiondispatch.exception.ActionNotFoundException;
import cn.yitun.chat.yitunactiondispatch.extend.ActionMessage;
import cn.yitun.chat.yitunactiondispatch.extend.ActionResponse;
import cn.yitun.chat.yitunactiondispatch.extend.ArgumentBox;
import cn.yitun.chat.yitunactiondispatch.extend.impl.DefaultArgumentBox;
import cn.yitun.chat.yitunchatbasesdk.server.im.dispatcher.handler.BaseMessageHandler;
import cn.yitun.chat.yituncommonlibutil.lib.YitunJsonUtil;
import cn.yitun.chat.yituncommonmessage.Head;
import cn.yitun.chat.yituncommonmessage.client.ClientHead;
import cn.yitun.chat.yituncommonmessage.impl.HeadImpl;
import cn.yitun.chat.yituncommonmessage.result.ResultMessage;
import cn.yitun.chat.yituncommonmessage.server.Result;
import cn.yitun.chat.yituncommonmessage.server.ServerHead;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Date 2019-01-17 21:48:32<br>
 * Description 处理消息，并调度方法
 * @author yitun
 * @since 1.1
 */
public class BaseMessageHandlerImpl implements BaseMessageHandler {

	protected Logger log = LoggerFactory.getLogger(SessionMessageHandlerImpl.class);

	private ActionDispatcher actionDispatcher;

	public BaseMessageHandlerImpl(ActionDispatcher actionDispatcher) {
		this.actionDispatcher = actionDispatcher;
	}

	public ActionDispatcher getActionDispatcher() {
		return actionDispatcher;
	}

	public void setActionDispatcher(ActionDispatcher actionDispatcher) {
		this.actionDispatcher = actionDispatcher;
	}

	@Override
	public Object doMessage(String message, String path, ActionResponse actionResponse, ArgumentBox argumentBox) {
		Object result = null;

		ActionMessage am = resolver(message, path, argumentBox);
		argumentBox.put(ActionResponse.class, actionResponse);
		try {
			result = actionDispatcher.action(am, actionResponse, argumentBox);
		} catch (ActionNotFoundException e) {

			ServerHead resultHead = getResultHead(message);
			Result r = new Result();
			r.setCode(HeadImpl.code_fail);
			r.setMessage("系统找不到方法！");
			resultHead.setResult(r);
			resultHead.setTimestamp(System.currentTimeMillis());

			ResultMessage m = new ResultMessage();
			m.setHead(resultHead);
			result = m;
		}
		return result;
	}

	private ServerHead getResultHead(String message) {
		ServerHead head = null;
		if (YitunJsonUtil.mayBeJSON(message)) {
			JsonObject jo = new JsonParser().parse(message).getAsJsonObject();
			boolean hasHead = jo.has("head");
			if (hasHead) {
				JsonObject headElement = jo.getAsJsonObject("head");
				head = new GsonBuilder().create().fromJson(headElement, ServerHead.class);
			}
		}
		if (null == head) {
			head = new ServerHead();
		}
		return head;
	}

	public ArgumentBox getArgumentBox() {
		ArgumentBox beanBox = new DefaultArgumentBox();
		return beanBox;
	}

	public ActionMessage resolver(Object requestData, String path, ArgumentBox argumentBox) {

		String message = (requestData instanceof String) ? requestData.toString() : "";
		if (YitunJsonUtil.maybeJSONObject(message)) {
			JsonObject jo = new JsonParser().parse(message).getAsJsonObject();
			boolean hasHead = jo.has("head");
			argumentBox.put(JsonObject.class, jo);

			if (hasHead) {
				JsonObject headElement = jo.getAsJsonObject("head");
				ClientHead head = new GsonBuilder().create().fromJson(headElement, ClientHead.class);

				argumentBox.put(Head.class, head);
				argumentBox.put(HeadImpl.class, head);
				argumentBox.put(ClientHead.class, head);
				String classCode = head.getAction();
				String methodCode = head.getMethod();
				if (null != classCode && !classCode.isEmpty() && null != methodCode && !methodCode.isEmpty()) {
					path = actionDispatcher.getActionRegistry().getPath(classCode, methodCode);
				}
			}
		}
		ActionMessage am = new ActionMessageImpl();
		am.setMessage(requestData);
		am.setAction(path == null ? "" : path);
		return am;
	}

	class ActionMessageImpl implements ActionMessage {

		Object message;
		String action;
		String method;

		@Override
		public void setMessage(Object message) {
			this.message = message;
		}

		@Override
		public Object getMessage() {
			return this.message;
		}

		@Override
		public String getAction() {
			return this.action;
		}

		@Override
		public void setAction(String action) {
			this.action = action;
		}
	}
}
